/*
 * (C) Copyright 2024 赤い月 All Rights Reserved.
 * Description：
 * Author：赤い月
 * Date: 2024/2/13
 * Modify Record:
 */

#include "Helpers/http_helper.h"
#include <QJsonDocument>
#include <QPixmap>

HttpUtils::HttpUtils(QObject* parent) : QObject(parent), store_cookie_{false} {
  manager_ = std::make_shared<QNetworkAccessManager>(this);
  connect(manager_.get(), &QNetworkAccessManager::finished, this,
          &HttpUtils::reply_finished);
}

void HttpUtils::logIn(const QString& username, const QString& password) {
  QVariantMap login_data;
  login_data["username"] = username;
  login_data["password"] = password;
  QJsonDocument json_doc = QJsonDocument::fromVariant(login_data);
  sendRequest("/login", json_doc.toJson(), true);
}

void HttpUtils::sendRequest(const QString& url,
                            const QByteArray& data,
                            const bool isPost) {
  QNetworkRequest request(QUrl(BASE_URL + url));
  configureSsl(request);
  setNetworkRequestHeader(request);

  if (isPost) {
    reply = manager_->post(request, data);
  } else {
    reply = manager_->get(request);
  }
}

void HttpUtils::getImage(const QString& url) {
  sendRequest(url);
}

void HttpUtils::getMusic(const QString& url) {
  sendRequest(url);
}

void HttpUtils::reply_finished(QNetworkReply* reply) {
  handleCookies(reply);

  auto data = readReply(reply);
  if (!data.isEmpty()) {
    if (reply->url().toString().endsWith(".png") ||
        reply->url().toString().endsWith(".jpg")) {
      QPixmap image;
      image.loadFromData(data);
      emit ImageDownloaded(image);
    } else if (reply->url().toString().endsWith(".mp3")) {
      emit MusicDownloaded(data);
    } else {
      emit ReplySignal(data);
    }
  }
  reply->deleteLater();
}

void HttpUtils::configureSsl(QNetworkRequest& request) {
  // SSL Configuration
  QSslConfiguration conf = request.sslConfiguration();
  // 关闭证书校验
  conf.setPeerVerifyMode(QSslSocket::VerifyNone);
  conf.setProtocol(QSsl::TlsV1_2OrLater);
  request.setSslConfiguration(conf);
}

void HttpUtils::setNetworkRequestHeader(QNetworkRequest& request) {
  // Setting cookies if available
  if (store_cookie_ && !stored_cookies_.isEmpty()) {
    QVariant var;
    var.setValue(stored_cookies_);
    request.setHeader(QNetworkRequest::CookieHeader, var);
  }
}

void HttpUtils::handleCookies(QNetworkReply* reply) {
  if (store_cookie_) {
    // Store the cookies from reply
    QList<QNetworkCookie> cookies = qvariant_cast<QList<QNetworkCookie>>(
        reply->header(QNetworkRequest::SetCookieHeader));
    if (!cookies.empty()) {
      stored_cookies_ = cookies;
    }
  }
}

QByteArray HttpUtils::readReply(QNetworkReply* reply) {
  return reply->readAll();
}
